
class MenuThing < Thing

  attribute :max_depth
  attribute :min_depth

  def creator e
    s = render e

    s << "hloubka od:"
    s << InputText.new(
        :name => form_id(:min_depth),
        :value => min_depth || 0,
        :size => 3
      ).to_s
    s << ' do: '
    s << InputText.new(
        :name => form_id(:max_depth),
        :value => max_depth,
        :size => 3
      ).to_s

    s
  end

  def recieve e
    ['max_depth', 'min_depth'].each { |attr|
      if v = e.params[form_id attr]
        self.send(attr+'=', v.to_i)
      end
    }
    super
  end

  def render e
    root = Tree.instance.root

    if min_depth && (min_depth > 0) && (dest = e.data['destination'])
      root = dest.path.reverse[min_depth-1]
    end

    render_menu root, e
  end

  def render_menu root, e
    return '' if !root

    items = 0
    range = ((min_depth || 0)..(max_depth || 10))

    root_ul = multiple_item_wrapper(root)
    root_ul.class_name << " MenuRoot"
    menu = { nil => root_ul }
    root.breadth_first { |node|
      next unless range.include? node.level
      li = single_item_wrapper(node, e)
      (menu[node.parent_node] || menu[nil]).append_child li
      if node.has_children? && range.include?(node.level+1)
        ul = multiple_item_wrapper(node)
        ul.class_name = 'sid-'+node.string_id
        li.append_child ul
        menu[node] = ul
      end
      items += 1
    }
    if items == 0
      widget.add_secondary_class 'empty'
      # hodit empty-menu do
    end

    if items == 0 && (min_depth == 0 || min_depth.nil?)
      "Click here to edit menu"
    else
      menu[nil].to_s
    end
  end

  def multiple_item_wrapper node
    ul = Element.new(:ul)
    ul.class_name = (node.string_id || '').dup
    ul.class_name << ' l'+node.level.to_s
    ul
  end

  def single_item_wrapper node, e
    el = Element.new(:li)
    el.append_child node.link(e).to_s
    el.class_name = 'l'+node.level.to_s
    if !node.string_id.nil? && !node.string_id.empty?
      el.class_name << ' sid-'+node.string_id
    end
    if node.first
      el.class_name << ' first'
    elsif node.last
      el.class_name << ' last'
    end
    if e.data['destination']
      if e.destination == node
        el.class_name << ' destination'
      end
      if e.destination.path.include? node
        el.class_name << ' on-path'
      end
    end
    el
  end

  def creator_form e
    "<div class=\"full_editor\">#{full_creator e}</div>"
  end

  def full_creator e
    if id = e.params['editing_identity']
      node = NodeThing.first(:identity => id)
    else
      node = NodeThing.all.select {|n| n.is_root }.first
    end

    if e.params['subpage']
      sub = NodeThing.new()
      sub.title = 'subpage'
      sub.parent_node = node
      sub.save
      node = sub
    else
      if e.params['id'] && e.params['id'].to_i == node.id
        node.recieve(e)
        if node.destroyed?
          if node.parent_identity
            node = NodeThing.first(:identity => node.parent_identity)
          else
            node = NodeThing.all.select {|n| n.is_root }.first
            if !node
              # maybe create default root
            end
          end
        end
      end
    end

    s = ''
    s << <<JS
<table width="100%">
<tr>
<td style="width:180px" valign="top">

  <div id="treeDiv1"></div>
  <div style="position:absolute;left:-20em">
    #{Element.new(:input, :type => :submit, :name => "NOOP", :value => "NOOP")}
  </div>
  <br/>
    #{Element.new(:input, :type => :submit, :value => '+ podstránka', :name => "subpage")}
  </br>

  <script>
  (function() {

    function addNodes(nodes, root, level) {
      for (var i = 0; i < nodes.length; i++) {
        var node = new YAHOO.widget.TextNode({
          label:nodes[i].label,
          node_id:nodes[i].id
        }, root, level < 1);
        if (nodes[i].children) {
         addNodes(nodes[i].children, node, level+1);
        }
      }
    }
    function treeInit(nodes) {
      var tree = new YAHOO.widget.TreeView("treeDiv1");
      addNodes(nodes, tree.getRoot(), 0);
      tree.draw();
      var field = document.getElementById('editing_identity');

      tree.subscribe("labelClick", function(node) {
          field.value = node.data.node_id;
          visual_editor_instance.submitForm(field.form);
          return false;
      });
    }
    treeInit(#{tree_json});
  })();

  </script>

</td>
<td valign="top">
JS

    if node
      s << node.creator_window(e)
      s << Element.new(
          :input,
          :type => :hidden,
          :name => 'editing_identity',
          :id => 'editing_identity',
          :value => node.identity
        ).to_s
    end

    s << '</td></tr></table>'


    wrap_in_form s
  end



  def tree_json
    nodes = NodeMenu.new.nodes

    i = 100

    data = []
    places = {}
    unprocessed = nodes[nil]
    while unprocessed.length > 0 && (i -= 1) > 0
      r = unprocessed.shift
      next if r.nil? #hot fix

      info = { :label => r.title || 'no title', :id => r.identity }
      places[r.identity] = info

      if !r.is_root
        (places[r.parent_identity][:children] ||= []).push(info)
      else
        data << info
      end

      unprocessed.push(*nodes[r.identity])
    end
    data.to_json
  end

end
